package org.ravey;

import java.util.ArrayList;
import java.util.Hashtable;

/**
 * Very simple, lightweight class for parsing and managing commandline options.
 * 
 * @author James Ravenscroft
 *
 */
public class CommandLineParser {
	

	 private Hashtable<String, String> options;
	 private ArrayList<String> arguments;
	 
	 public CommandLineParser(){
		//create a hashtable to handle options
		 options = new Hashtable<String, String>();
		//create a list for catching positional arguments
		 arguments = new ArrayList<String>();
	 }
	 
	 /**
	  * Parse an array of options and arguments straight off the commandline
	  * @param args the args array from your main() function
	  */
	 public void parse(String[] args){
		 
		 
		 //if we have some args, we need to take care of them
		 if(args.length > 0){
			 
			 //iterate over the arguments
			 for(int i=0;i<args.length;i++){
				 
				 //if the arg starts with -- its an option
				 if(args[i].startsWith("--")){

					 
					 String key = "";
					 String value = "";
					 
					 //see if the string contains an equals
					 int eq = args[i].indexOf("=");
					 
					 //if the arg contains an equals sign then its an option=value arg
					 if(eq > 1){
						 key = args[i].substring(2,eq);
						 value = args[i].substring(eq+1);
					 }
					 //if this didn't work then its probably an --option value pair
					 else if(i+1 < args.length){
						 //save the options pair
						 key = args[i].substring(2);
						 value = args[i+1];
						 i++;
						 
					 }
					 //if this didn't work then just list the option as true in the table
					 else{
						 key = args[i].substring(2);
						 value = "true";
					 }
					 
					 
					 //---------------space character escape parsing---------------
					 
					 
					//if the argument ends with a backslash then start escaping
					 if(value.endsWith("\\")){
						 while(value.endsWith("\\") && (i<args.length)){
							 value = value.substring(0,value.length() - 1).concat(" " + args[i+1]);
							 i++;
							 
						 }
					 }
					 
					 //if the value starts with quotation marks, start escaping
					 if(value.startsWith("\"")){
						 value = value.substring(1);
						 
						 while(!value.endsWith("\"") && (i<args.length)){
							 value = value.concat(" " + args[i+1]);
							 i++;
						 }
						 
						 //now strip away that stupid quotemark
						 value = value.substring(0, value.length()-1);
						 
			
					 }
					 
					 //if the value starts with single quotation marks, start escaping
					 if(value.startsWith("'")){
						 value = value.substring(1);
						 
						 while(!value.endsWith("'") && (i<args.length)){
							 value = value.concat(" " + args[i+1]);
							 i++;
						 }
						 
						 //now strip away that stupid quotemark
						 value = value.substring(0, value.length()-1);
						 
			
					 }
					 
					 
					 //save the option to the actual array
					 options.put(key, value);
					 
					 
					 
				 }//end arg startswith "--"
				 
				 //if the arg starts with - then its a switch
				 else if(args[i].startsWith("-")){
					 options.put(args[i].substring(1), "true");
				 }
				 //finally, if it starts with neither a - or -- then its just a positional argument
				 else{
					 
					 String arg = args[i];
					 
					 //---------------space character escape parsing---------------
					 
					 
						//if the argument ends with a backslash then start escaping
						 if(arg.endsWith("\\")){
							 while(arg.endsWith("\\") && (i<args.length)){
								 arg = arg.substring(0,arg.length() - 1).concat(" " + args[i+1]);
								 i++;
								 
							 }
						 }
						 
						 //if the arg starts with quotation marks, start escaping
						 if(arg.startsWith("\"")){
							 arg = arg.substring(1);
							 
							 while(!arg.endsWith("\"") && (i<args.length)){
								 arg = arg.concat(" " + args[i+1]);
								 i++;
							 }
							 
							 //now strip away that stupid quotemark
							 arg = arg.substring(0, arg.length()-1);
							 
				
						 }
						 
						 //if the arg starts with single quotation marks, start escaping
						 if(arg.startsWith("'")){
							 arg = arg.substring(1);
							 
							 while(!arg.endsWith("'") && (i<args.length)){
								 arg = arg.concat(" " + args[i+1]);
								 i++;
							 }
							 
							 //now strip away that stupid quotemark
							 arg = arg.substring(0, arg.length()-1);
							 
				
						 }
					 
					 
					 
					 arguments.add(arg);
				 }
				 
			 }//end argument iteration
			 
			 
		 }//end args handler
		 
	 }

	 /**
	  * Get function for accessing parsed options
	  * 
	  * Get function for accessing parsed options 
	  * You should run parse() first to avoid dissapointment
	  * 
	  * @return list of options parsed from the commandline
	  * @see parse(String[] args)
	  */
	 public Hashtable<String,String> GetOptions(){
		 return options;
	 }
	 
	 /**
	  * Get function for accessing parsed arguments
	  * 
	  * Get function for accessing parsed arguments 
	  * You should run parse() first to avoid dissapointment
	  * 
	  * @return list of options parsed from the commandline
	  * @see parse(String[] args)
	  */
	 public ArrayList<String> GetArguments(){
		 return arguments;
	 }

}
